//
//  AppDelegate.m
//  NSThreadTest
//
//  Created by wangrui on 14-2-26.
//  Copyright (c) 2014年 Ourui. All rights reserved.
//

#import "AppDelegate.h"
#import "TestObject.h"
#import "pthread.h"

@interface AppDelegate ()
{
    NSLock *_theLock;
    NSCondition *_theCondition;
}

@property(nonatomic,strong)NSMutableArray *products;
@property (strong) NSLock *lock;
@property (strong) NSConditionLock *conditionLock;
@end

@implementation AppDelegate

void * doSomethingC(void *a)
{
	printf("pthread:%d\n", * (int *)a);
	
	sleep(5.0);
	
	printf("Sleep Over\n");
	
	return NULL;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
	self.window.rootViewController = [UIViewController new];
    [self.window makeKeyAndVisible];
    
    
    //测试-: 线程于autorelease pool问题
    //[[TestObject new] runTest];
    
    //测试二: Lock 问题
    //当一个线程获取到一个lock时,其他线程再获取这个lock, 就会进入wait状态
    
//    self.lock = [[NSLock new] autorelease];
//    self.conditionLock = [[[NSConditionLock alloc] initWithCondition:3] autorelease];
//    //创建三个线程
//    [NSThread detachNewThreadSelector:@selector(dosomthing:) toTarget:self withObject:nil];
//    [NSThread detachNewThreadSelector:@selector(dosomthing:) toTarget:self withObject:nil];
//    [NSThread detachNewThreadSelector:@selector(dosomthing:) toTarget:self withObject:nil];
    

    //测试3: pthread 创建
//	pthread_t thread;
//	int integer = 5;
//	int err = pthread_create(&thread,NULL,doSomethingC,&integer);
//	
//	if (err == 0) {
//		pthread_join(thread,NULL); //阻塞调用线程
//		
//		for (int i=0; i<10; i++) {
//			printf("main thread\n");
//		}
//	}

    
    [self testProduceConsume];
    
    return YES;
}

static int curse = 0;

- (void)printData{
    /*
     2014-02-26 20:48:53.315 NSThreadTest[3496:3903] 4865
     2014-02-26 20:48:53.316 NSThreadTest[3496:320b] 4846
     2014-02-26 20:48:53.316 NSThreadTest[3496:3e03] 4954
     */
    //不加锁时输出是乱的
    for (int i=0; i<100; i++) {
        NSLog(@"%@,%d",[NSThread currentThread],i);
        curse++;
    }
}

- (void)dosomthing:(id)sender{
    //[self normalLock];
    [self conditionLockTest];
}

- (void)normalLock{
    [self.lock lock];
    [self printData];
    [self.lock unlock];
}

- (void)conditionLockTest{
    [self.conditionLock lockWhenCondition:3];
    [self printData];
    [self.conditionLock unlockWithCondition:3];//如果不为3,一直没解锁，只有一个线程输出
}

#pragma mark - Consume & Produce

static NSUInteger maxProduct = 100;

- (void)testProduceConsume {
    self.products = [NSMutableArray array];
    _theLock = [[NSLock alloc]init];
    _theCondition = [[NSCondition alloc] init];
    
    
//1
//    for (int i=0; i<50000; i++) {
//        dispatch_async(dispatch_get_global_queue(0, 0), ^{
//            [self produce];
//        });
//        
//        
//        dispatch_async(dispatch_get_global_queue(0, 0), ^{
//            [self consum];
//        });
//        
//    }
    
//2
//    for (int i=0; i<50000; i++) {
//        dispatch_async(dispatch_get_global_queue(0, 0), ^{
//            [self produce2];
//        });
//        
//        
//        dispatch_async(dispatch_get_global_queue(0, 0), ^{
//            [self consum2];
//        });
//        
//    }
}

- (void)produce {
    [_theLock lock];
    
    if (self.products.count > maxProduct) {
        
    }
    else {
        [self.products addObject:@"i"];
    }
    
    [_theLock unlock];
    
    NSLog(@"produce:%lu",(unsigned long)self.products.count);
}

- (void)consum {
    
    [_theLock lock];
    
    if (self.products.count > 0) {
        [self.products removeObjectAtIndex:0];
    }
    
    [_theLock unlock];
    
    NSLog(@"consum:%lu",(unsigned long)self.products.count);
}

- (void)produce2 {
    
    [_theCondition lock];
    
    if (self.products.count > maxProduct) {
         [_theCondition wait];
    }
   
    [self.products addObject:@"i"];
    [_theCondition signal];
    
    [_theCondition unlock];
    
    NSLog(@"produce:%lu",(unsigned long)self.products.count);
}

- (void)consum2 {
 
    [_theCondition lock];
    
    while ( self.products.count <= 0) {
        
        [_theCondition wait]; //会放弃锁资源，其他线程调用 lock 会成功
        
    }
    
    [self.products removeObjectAtIndex:0];
    
    [_theCondition unlock];
    
    
    NSLog(@"consum:%lu",(unsigned long)self.products.count);
}




@end
